﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI;
using System;

public class CameraModelCtr : MonoBehaviour, IViewerDrawer
{
    private static CameraModelCtr mCameraModelCtr = null;
    public static CameraModelCtr Ins
    {
        get { return mCameraModelCtr; }
    }

    #region UI
    public PanelTween pageTweem;
    public UGUIToggle loopToggle;
    public GameObject frameBtnRoot;
    public Slider speedSlider;
    public Text curSpeed;
    public Transform modelRoot;
    public Text frameNumTex,frameSecTex;
    #endregion

    #region prop
    /// <summary>
    /// 动画每秒帧数
    /// </summary>
    private int AnimFrameCount = 30;
    private Animator animator;
    private GameObject modelPrefab;

    /// <summary>
    /// 帧数据管理
    /// </summary>
    private AnimClipInfoCtr animInfoCtr;

    /// <summary>
    /// 当前处理的动画显示信息
    /// </summary>
    private AnimClipInfo curAnimClipInfo;
    /// <summary>
    /// 当前处理的动作显示信息
    /// </summary>
    private ActionClipInfo curActionClipInfo;

    private CameraPlayLogic playLogic;
    #endregion

    #region boxProp
    private CuboidDrawer selfBox;
    private Data.ActionGroup selfData;
    #endregion

    /// <summary>
    /// null没有
    /// </summary>
    /// <param name="animName"></param>
    /// <returns></returns>
    public AnimClipInfo GetAnimClip(string animName)
    {
        if (animInfoCtr == null)
        {
            return null;
        }
        return animInfoCtr.GetOneAnimClipFrames(animName);
    }

    #region LoadAnimInfoModels
    public void SetModel(string modelPath , string controllerPath)
    {
         StartCoroutine(LoadModelsAll(modelPath, controllerPath));
    }

    IEnumerator LoadModelsAll(string modelPath, string controllerPath)
    {
        string ass = "Assets";
        var resPath = modelPath.Replace("\\", "/").Substring(Application.dataPath.Length - ass.Length);
        var modelOrg = ActionEditorInterface.LoadAssetAtPath<GameObject>(resPath); /*AssetDatabase.LoadAssetAtPath<GameObject>(resPath);*/
        modelPrefab = Instantiate<GameObject>(modelOrg, modelRoot);
        yield return 1;

        var contrPath = controllerPath.Substring(Application.dataPath.Length - ass.Length);
        var contrOrg = ActionEditorInterface.LoadAssetAtPath<RuntimeAnimatorController>(contrPath); /*AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(contrPath);*/
        //var contrRes = AssetDatabase。 <RuntimeAnimatorController>(contrOrg);
        
        animator = modelPrefab.GetComponent<Animator>();
        animator.runtimeAnimatorController = contrOrg;
        yield return 1;
        //animator.Play("Idel");
        animator.SetFloat("Blend", 1);

        CreateAnimClipInfoCtr(animator);
    }
    /// <summary>
    /// 创建所有动画信息
    /// </summary>
    /// <param name="anim"></param>
    private void CreateAnimClipInfoCtr(Animator anim)
    {
        animInfoCtr = new AnimClipInfoCtr();
        var clips = anim.runtimeAnimatorController.animationClips;
        foreach (var clip in clips)
        {
            animInfoCtr.AddAnimClip(clip.name, clip);
        }
        frameBtnRoot.SetActive(true);

        playLogic = new CameraPlayLogic(this);

        if (selfBox == null)
        {
            selfBox = ModelDrawerTool.Instance.Spawn<CuboidDrawer>();
            selfBox.transform.SetParent(/*modelRoot*/modelPrefab.transform);
            TransformUtility.ResetTransform(selfBox.transform);
            selfBox.SetBoxCollider();
            selfBox.RefreshColor(new Color(0, 44f / 255, 1, 87f / 255));
        }
    }
    #endregion

    #region UI Select Action Event
    private void OnEnable()
    {
        mCameraModelCtr = this;
        Register();
        loopToggle.onValueChangedEvent = OnLoopToggle;
    }
    private void OnDisable()
    {
        UnRegister();
    }
    private void OnLoopToggle(object obj ,bool value)
    {
        if (playLogic != null)
        {
            playLogic.ChangLoopModule(value);
        }
    }
    private void Register()
    {
        EventManager.AddEventListener<FrameInfo>(CommonEvent.Select_One_FrameLine, OnSelect_One_FrameLine);
        EventManager.AddEventListener<string>(CommonEvent.SelectOneAnimSlot, OnSelectOneAnimSlot);
        EventManager.AddEventListener<ActionClipInfo>(CommonEvent.SelectOneActionDataToCameraCtr0, OnSelectOneActionData);
    }
    private void UnRegister()
    {
        EventManager.AddEventListener<FrameInfo>(CommonEvent.Select_One_FrameLine, OnSelect_One_FrameLine);
        EventManager.RemoveEventListener<string>(CommonEvent.SelectOneAnimSlot, OnSelectOneAnimSlot);
        EventManager.RemoveEventListener<ActionClipInfo>(CommonEvent.SelectOneActionDataToCameraCtr0, OnSelectOneActionData);
    }
    private void OnSelect_One_FrameLine(FrameInfo info)
    {
        playLogic.PauseOneFrame(info);
    }
    /// <summary>
    /// 选择一个动作
    /// </summary>
    /// <param name="action"></param>
    private void OnSelectOneActionData(ActionClipInfo action)
    {
        if (playLogic != null)
        {
            curAnimClipInfo = null;
            curActionClipInfo = action;
            playLogic.RefrshCurrentData(action.FrameCount, action.AnimName, action.GetFrameInfo(), action.AnimTime,action.startNormarlizeTime);

            //给帧列表刷新下信息
            EventManager.TriggerEvent<ActionClipInfo, AnimClipInfo>(CommonEvent.OpenFrameLinePanel, curActionClipInfo, curAnimClipInfo);

            if (selfData == null)
            {
                selfData = EActionDataCtr.Instance.CurGroupData();
            }
        }
    }
    /// <summary>
    /// 选择一个动画 
    /// </summary>
    /// <param name="targetAnim"></param>
    private void OnSelectOneAnimSlot(string targetAnim)
    {
        curActionClipInfo = null;
        curAnimClipInfo = animInfoCtr.GetOneAnimClipFrames(targetAnim);
        playLogic.RefrshCurrentData(curAnimClipInfo.FrameCount,
            curAnimClipInfo.AnimName,curAnimClipInfo.GetFrameList(),curAnimClipInfo.AnimTime);

        //给帧列表刷新下信息
        EventManager.TriggerEvent<ActionClipInfo, AnimClipInfo>(CommonEvent.OpenFrameLinePanel, curActionClipInfo, curAnimClipInfo);
    }
    #endregion

    private void Update()
    {
        if (playLogic != null)
        {
            playLogic.Update();
        }
    }

    #region animtor play Btn Event
    /// <summary>
    /// 向前播放一帧
    /// </summary>
    public void PlayAnimatorForwad()
    {
        playLogic.PlayForward();
    }

    /// <summary>
    /// 向后播放一帧
    /// </summary>
    public void PlayAnimatorReverse()
    {
        playLogic.PlayReverse();
    }
    
    /// <summary>
    /// 暂停或播放
    /// </summary>
    public void Play()
    {
        playLogic.Play();
    }

    /// <summary>
    /// 变更播放速度
    /// </summary>
    public void ChangeSpeed()
    {
        var speed =  ((int)(speedSlider.value* 20)) / 10f;
        curSpeed.text = speed.ToString("0.0");
        //set logic speed
        playLogic.ChangeSpeed(speed);
    }

    /// <summary>
    /// 打开帧列表
    /// </summary>
    public void FrameLine()
    {
        if (curActionClipInfo != null|| curAnimClipInfo!=null)
        {
            bool open = pageTweem.IsFrameLineOpen();
            pageTweem.OpenFrameLineTween(open); //打开时候才激活这个时候面板 不一定能接受到事件 ，事件在Enbale上注册的？ 要等下一帧

            EventManager.TriggerEvent<ActionClipInfo,AnimClipInfo>(CommonEvent.OpenFrameLinePanel, curActionClipInfo,curAnimClipInfo);
        }
        else 
        {
            FucTempLog.LogError("请选择一个动作数据");
        }
    }
    #endregion

    #region drawer viewer
    public void PlayAnim(string animName, int Layer, float normalizedTime)
    {
        animator.Play(animName, 0, normalizedTime);
    }

    public void PlayCrossFade(FrameInfo info, int frameIndex, float speed)
    {
        animator.CrossFade(info.animName, 0.15f, 0, 0);
        animator.speed = speed;
    }

    public void SetAnimSpeed(float speed)
    {
        animator.speed = speed;
    }
    System.Text.StringBuilder str = new System.Text.StringBuilder();
    public void RefreshFrameText(FrameInfo info, int frameIndex,int allFrameNum)
    {
        frameNumTex.text = string.Format("{0}/{1} | {2}", frameIndex, allFrameNum, Mathf.Clamp(frameIndex*100f/ allFrameNum,0,100));
        str.Remove(0,str.Length);
        str.Append(info.FrameTime.ToString("0.000")); /*str.Append(":");str.Append((int)((info.FrameTime % 1)*10000));*/
        //frameSecTex.text = Mathf.FloorToInt(info.FrameTime) + ":" + (info.FrameTime % 1)/100;
        frameSecTex.text = str.ToString();
    }

    public void RefreshAnimator(FrameInfo info, int frameIndex, float speed)
    {
        animator.Play(info.animName,0,info.normalizedTime);
        //animator.CrossFade(info.animName, 0.15f, 0, info.normalizedTime);
        animator.speed = speed;
    }

    public void RefresFrameEvent(FrameInfo info, int frameIndex)
    {
       
    }

    public void RefreshIntterrupt(FrameInfo info, int frameIndex)
    {
       
    }

    void IViewerDrawer.RefreshAttackDef(FrameInfo info, int frameIndex)
    {
       
    }

    float sizeModifiy = 0.001f * 0.01f;
    UnityEngine.Vector3 realyModeLocalScale = UnityEngine.Vector3.one;
    /// <summary>
    /// 根据配置数据初始化自己的包围盒大小，并同步碰撞盒大小
    /// </summary>
    public void RefreshSelfBox()
    {
        if (curActionClipInfo != null)
        {
            //Action下的 bundle 缩放比率 [0 - 100]
            var actionBundRadio = curActionClipInfo.GetActionBoundleRotate();
            var size = new Vector3(
                selfData.BoundingWidth * actionBundRadio.x * sizeModifiy, //x
                 selfData.BoundingHeight * actionBundRadio.y * sizeModifiy,//y
                 selfData.BoundingLength * actionBundRadio.z * sizeModifiy);//z
           
            selfBox.InitDrawCube(size.x, size.y, size.z,
                 selfData.BoundingWidthOffset * 0.001f, //x
                 selfData.BoundingHeightOffset * 0.001f,//y
                 selfData.BoundingLengthOffset * 0.001f//z
               );
        }
    }

    /// <summary>
    /// 根据绘制器上的BoxCollider自动调整并保存碰撞框大小
    /// </summary>
    public Vector3[] RefrshSelfBox()
    {
       return selfBox.RefreshCubeData(selfData);
    }

    public void PlayCrossFade(string animName, float speed, float transitionDuration = 0.15f)
    {
        animator.CrossFade(animName, transitionDuration, 0, speed);
        animator.speed = speed;
    }

    #endregion

}
